﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.TeamFoundation.TestManagement.Client;
using Microsoft.TeamFoundation.Lab.Workflow.Activities;

namespace HybridLab.Workflow.Activities.UI
{
	internal partial class TestDetailsPage : UserControl
	{
		private bool canUpdateTestSetting;
        private RunTestDetailsEx testDetails;
		private HybridLabWizardData wizardData;
        private bool dataLoaded;
        private bool testPlanLoaded;

        private TestDetailsPage()
        {
            canUpdateTestSetting = true;
            InitializeComponent();
            browseSuitesButton.Text = "...";
            testPlanLayoutPanel.Enabled = false;
        }

        internal TestDetailsPage(RunTestDetailsEx details, bool wizardMode)
            : this()
        {
            if (details == null)
            {
                throw new ArgumentNullException("details");
            }
            testDetails = details;
            runTestCheckBox.Visible = wizardMode;
            Initialize();
        }

		internal TestDetailsPage(HybridLabWizardData wizardData)
            : this(wizardData.TestDetails, true)
        {
            base.Enabled = false;
            this.wizardData = wizardData;
            this.wizardData.DataLoadCompleted += new EventHandler(wizardData_DataLoadCompleted);
        }

        void wizardData_DataLoadCompleted(object sender, EventArgs e)
        {
            base.Enabled = true;
            if (testPlanLoaded)
            {
                FilterTestSettings();
            }
            dataLoaded = true;
            wizardData.EnvironmentDetails.EnvironmentChanged += new EventHandler(EnvironmentDetails_EnvironmentChanged);
        }

        private void FilterTestSettings()
        {
            List<string> roles = null;
            if (wizardData.EnvironmentDetails.Environment != null && TestSettingsList != null)
            {
                ITestEnvironment env = wizardData.EnvironmentDetails.Environment;
                roles = new List<string>();
                foreach (IMachineRole role in env.MachineRoles)
                {
                    if (!roles.Contains(role.Name))
                    {
                        roles.Add(role.Name);
                    }
                }
            }
			testDetails.FilterTestSettings(roles);
            UpdateTestSettingsList();
        }

        void EnvironmentDetails_EnvironmentChanged(object sender, EventArgs e)
        {
            FilterTestSettings();
        }

        private void AttachHandlers()
        {
            browseSuitesButton.Click += new EventHandler(browseSuitesButton_Click);
            runTestCheckBox.CheckedChanged += new EventHandler(runTestCheckBox_CheckedChanged);
            testPlanComboBox.SelectedIndexChanged += new EventHandler(testPlanComboBox_SelectedIndexChanged);
            testConfigurationComboBox.SelectedIndexChanged += new EventHandler(testConfigurationComboBox_SelectedIndexChanged);
            testSettingsComboBox.SelectedIndexChanged += new EventHandler(testSettingsComboBox_SelectedIndexChanged);
        }

        private void browseSuitesButton_Click(object sender, EventArgs e)
        {
            ShowTestSuiteSelectionDialog();
        }

        private void Initialize()
        {
            testDetails.Initialized += new EventHandler(details_Initialized);
            testDetails.ErrorChanged += new EventHandler(details_ErrorChanged);
            InitializeErrorProviders();
            RefreshErrors();
        }

        private void InitializeErrorProviders()
        {
			testPlanListErrorProvider = WizardUtils.CreateErrorProvider(testPlanComboBox);
			testConfigurationListErrorProvider = WizardUtils.CreateErrorProvider(testConfigurationComboBox);
			testSettingsListErrorProvider = WizardUtils.CreateErrorProvider(testSettingsComboBox);
        }

        private void details_ErrorChanged(object sender, EventArgs e)
        {
            RefreshErrors();
        }

        private void details_Initialized(object sender, EventArgs e)
        {
            TestPlanLoaded();
        }

        private void RefreshErrors()
        {
            string err = testDetails["TestPlanList"];
            testPlanListErrorProvider.SetError(testPlanComboBox, err);
			var enable = string.IsNullOrEmpty(err) && testDetails.RunTest;
            testPlanLayoutPanel.Enabled = testPlanComboBox.Enabled = enable;
            
			err = testDetails["TestConfigurationList"];
            testConfigurationListErrorProvider.SetError(testConfigurationComboBox, err);
			testConfigurationComboBox.Enabled = string.IsNullOrEmpty(err) && testDetails.RunTest;
            
			err = testDetails["AutomatedTestSettingsList"];
            testSettingsListErrorProvider.SetError(testSettingsComboBox, err);
			testSettingsComboBox.Enabled = string.IsNullOrEmpty(err) && testDetails.RunTest;
        }

        private void runTestCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetRunTestMode(this.runTestCheckBox.Checked);
            RefreshErrors();
        }

        private void SetCurrentTestPlan(ITestPlan testPlan)
        {
            if (testPlan != null)
            {
                testPlanComboBox.SelectedItem = testPlan;
            }
            else
            {
                testPlanComboBox.SelectedIndex = 0;
            }
            TestPropertiesLoaded();
        }

        private void SetRunTestMode(bool enable)
        {
            runTestCheckBox.Checked = enable;
            testPlanLabel.Enabled = enable;
            testPlanComboBox.Enabled = enable;
            testPlanLayoutPanel.Enabled = enable;
            testDetails.RunTest = enable;
        }

        private void ShowSelectedTestSuites()
        {
			testSuitesTextBox.Text = RunTestDetails.GetSuiteNames(testDetails.Suites);
        }

        private void ShowTestSuiteSelectionDialog()
        {
            using (TestSuiteDialog suite = new TestSuiteDialog(testDetails.TestSuiteList, testDetails.Suites))
            {
                if ((suite != null) && (suite.ShowDialog() == DialogResult.OK))
                {
                    testDetails.Suites = suite.SelectedSuites;
                    ShowSelectedTestSuites();
                }
            }
        }

        private void testConfigurationComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            testDetails.TestConfiguration = testConfigurationComboBox.SelectedItem as ITestConfiguration;
        }

        private void testPlanComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            testDetails.TestPlan = testPlanComboBox.SelectedItem as ITestPlan;
            TestPropertiesLoaded();
        }

        protected virtual void TestPlanLoaded()
        {
            if ((testDetails.TestPlanList != null) && (testDetails.TestPlanList.Count > 0))
            {
                testPlanComboBox.DisplayMember = "Name";
                testPlanComboBox.DataSource = testDetails.TestPlanList;
                testPlanComboBox.Enabled = true;
                testSettingsComboBox.DataSource = testDetails.AutomatedTestSettingsList;
                testSettingsComboBox.DisplayMember = "Name";
                testConfigurationComboBox.DataSource = testDetails.TestConfigurationList;
                testConfigurationComboBox.DisplayMember = "Name";
                SetCurrentTestPlan(testDetails.TestPlan);
                RefreshErrors();
                testPlanLayoutPanel.Enabled = true;
            }
            else
            {
                scriptErrorControl = new ErrorControl(testPlanLayoutPanel.Size);
                noPlanErrorPanel.Controls.Add(scriptErrorControl, 0, 3);
                scriptErrorControl.SetErrorMessage("The current project does not contain any test plans");
            }
            AttachHandlers();

            if (dataLoaded)
            {
                FilterTestSettings();
            }
            testPlanLoaded = true;
        }

        private void TestPropertiesLoaded()
        {
            testPlanLayoutPanel.Enabled = true;
            UpdateUI();
            UpdateSelections();
        }

        private void testSettingsComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (canUpdateTestSetting)
            {
                testDetails.TestSettings = testSettingsComboBox.SelectedItem as ITestSettings;
            }
        }

        private void UpdateSelections()
        {
            ITestPlan currentPlan = testDetails.TestPlan;
            int testConfigId = (testDetails.TestConfiguration != null) ? testDetails.TestConfiguration.Id : -1;
            ITestConfiguration configuration = testDetails.TestConfigurationList.FirstOrDefault(c => c.Id == testConfigId);
            if (currentPlan != null && configuration == null && currentPlan.RootSuite.DefaultConfigurations.Count() > 0)
            {
                configuration = testDetails.TestConfigurationList.FirstOrDefault(c => c.Id == currentPlan.RootSuite.DefaultConfigurations[0].Id);
            }
            if (configuration != null)
            {
                testConfigurationComboBox.SelectedItem = configuration;
                testDetails.TestConfiguration = configuration;
            }
            UpdateTestSettingSelection(testDetails.AutomatedTestSettingsList);
            if (testDetails.Suites == null || testDetails.Suites.Count == 0)
            {
                testDetails.Suites = new List<ITestSuiteBase>();
                testDetails.Suites.Add(currentPlan.RootSuite);
            }
            ShowSelectedTestSuites();
        }

        private void UpdateTestSettingSelection(List<ITestSettings> list)
        {
            ITestSettings settings = testDetails.TestSettings;
            if (list != null && list.Count > 0)
            {
				if (settings != null && list.Any(s => s.Id == settings.Id))
				{
					testSettingsComboBox.SelectedItem = settings;
					testDetails.TestSettings = settings;
				}
				else
				{
					settings = list[0];
					testDetails.TestSettings = settings;
				}
            }
        }

        protected void UpdateTestSettingsList()
        {
            if (testDetails.TestPlanList != null && testDetails.TestPlanList.Count > 0)
            {
                canUpdateTestSetting = false;
                testSettingsComboBox.DataSource = testDetails.CurrentTestSettingsList;
                UpdateTestSettingSelection(testDetails.CurrentTestSettingsList);
                canUpdateTestSetting = true;
            }
        }

        private void UpdateUI()
        {
            SetRunTestMode(testDetails.RunTest);
            int planId = (testDetails.TestPlan != null) ? testDetails.TestPlan.Id : -1;
            testPlanComboBox.SelectedItem = testDetails.TestPlanList.FirstOrDefault(p => p.Id == planId);
        }

        internal List<ITestSettings> TestSettingsList
        {
            get
            {
                return testDetails.AutomatedTestSettingsList;
            }
        }
	}
}
